/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package operators;

import metadata.SystemMetaData;
import metadata.TableMetaData;

/**
 *
 * @author Dragan
 */
public class HashJoin extends Operation {

    protected SystemMetaData systemMetaData;
    protected TableMetaData table1MetaData;
    protected TableMetaData table2MetaData;
    protected long inputSize1;
    protected long inputSize2;

    public HashJoin(SystemMetaData systemMetaData, TableMetaData table1MetaData, TableMetaData table2MetaData, long inputSize1, long inputSize2) {
        this.systemMetaData = systemMetaData;
        this.table1MetaData = table1MetaData;
        this.table2MetaData = table2MetaData;
        this.inputSize1 = inputSize1;
        this.inputSize2 = inputSize2;
        this.operationName = "HashJoin";
        execute();
    }

    @Override
    protected void execute() {
        long hb = systemMetaData.getHybridHashJoinBufferSizeInBytes();
        long t1 = table1MetaData.getTupleSizeInBytes();
        long hashPartitions = (long) Math.ceil(inputSize1 * t1 / hb);
        if (hashPartitions == 1) {
            diskCost = 0;
        } else {
            long t2 = table2MetaData.getTupleSizeInBytes();
            long b = systemMetaData.getDiskPageSizeInBytes();
            diskCost = ((long) Math.ceil(inputSize2 * t2 / b)) * hashPartitions;
        }
        outputSize = (inputSize1 * inputSize2) / table1MetaData.getNumberOfTuples();
    }

    @Override
    public String toString() {
        String str = "";
        str += " t1:" + table1MetaData.getTableName() + " t2:" + table2MetaData.getTableName() + " input1:" + this.inputSize1 + " input2:" + this.inputSize2;
        return this.operationName + str + " " + super.toString();
    }
}
